﻿
#region - 版 本 注 释 -
/*----------------------------------------------------------------
 * 版权所有 (c) 2024   保留所有权利。
 * CLR版本：4.0.30319.42000
 * 机器名称：DESKTOP-GLJ2Q8J
 * 公司名称：
 * 命名空间：AutoCAD.EntityTool
 * 唯一标识：b893f674-d9d1-4fd6-88a5-6b43f5b1d8e0
 * 文件名：BlockTools
 * 当前用户域：DESKTOP-GLJ2Q8J
 * 
 * 创建者：Guo-79991
 * 电子邮箱：799919859@qq.com
 * 创建时间：2024/7/15 12:05:36
 * 版本：V1.0.0
 *
 * 功能描述(Description):
 * 参考文档(Reference):
 * 数据表(Tables):
 * 作者(Author):Guo
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion - 版 本 注 释 -

namespace AutoCAD.EntityTools.Convert
{
    public class DwgToDxfConverter
    {
        /// <summary>
        /// 将DWG文件转换为DXF格式
        /// </summary>
        /// <param name="sourceDwgPath">源DWG文件路径</param>
        /// <param name="targetDxfPath">目标DXF文件路径</param>
        /// <param name="dxfVersion">DXF版本（默认：AC1027 - AutoCAD 2013）</param>
        /// <returns>转换是否成功</returns>
        public static bool ConvertDwgToDxf(string sourceDwgPath, string targetDxfPath, string dxfVersion = "AC1027")
        {
            if (string.IsNullOrEmpty(sourceDwgPath))
                throw new ArgumentNullException(nameof(sourceDwgPath));

            if (string.IsNullOrEmpty(targetDxfPath))
                throw new ArgumentNullException(nameof(targetDxfPath));

            if (!File.Exists(sourceDwgPath))
                throw new FileNotFoundException("源DWG文件不存在", sourceDwgPath);

            // 检查目标目录是否存在，不存在则创建
            string targetDirectory = Path.GetDirectoryName(targetDxfPath);
            if (!Directory.Exists(targetDirectory))
            {
                Directory.CreateDirectory(targetDirectory);
            }

            Database database = null;
            bool success = false;

            try
            {
                // 等待文件释放
                if (!WaitForFileRelease(sourceDwgPath, 5000))
                {
                    throw new IOException($"文件被占用，无法访问: {sourceDwgPath}");
                }

                // 创建新的数据库实例
                database = new Database(false, true);

                // 读取DWG文件，使用FileShare.ReadWrite避免共享冲突
                database.ReadDwgFile(sourceDwgPath, FileShare.ReadWrite, true, "");

                // 保存为DXF文件
                database.SaveAs(targetDxfPath, DwgVersion.Current);

                success = true;
                return true;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception acEx)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"AutoCAD错误: {acEx.Message}\n");
                return false;
            }
            catch (System.Exception ex)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"转换错误: {ex.Message}\n");
                return false;
            }
            finally
            {
                // 清理资源
                if (database != null)
                {
                    database.Dispose();
                    database = null;
                }
            }
        }

        /// <summary>
        /// 等待文件释放
        /// </summary>
        private static bool WaitForFileRelease(string filePath, int timeoutMs, int retryIntervalMs = 100)
        {
            int elapsed = 0;
            while (elapsed < timeoutMs)
            {
                try
                {
                    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        // 文件可访问
                        return true;
                    }
                }
                catch (IOException)
                {
                    // 文件被占用，等待后重试
                    Thread.Sleep(retryIntervalMs);
                    elapsed += retryIntervalMs;
                }
            }
            return false;
        }

        /// <summary>
        /// 批量转换DWG文件为DXF格式
        /// </summary>
        public static int BatchConvertDwgToDxf(string sourceDirectory, string targetDirectory,
                                              string searchPattern = "*.dwg", string dxfVersion = "AC1027")
        {
            if (!Directory.Exists(sourceDirectory))
                throw new DirectoryNotFoundException($"源目录不存在: {sourceDirectory}");

            if (!Directory.Exists(targetDirectory))
                Directory.CreateDirectory(targetDirectory);

            string[] dwgFiles = Directory.GetFiles(sourceDirectory, searchPattern);
            int successCount = 0;

            foreach (string dwgFile in dwgFiles)
            {
                try
                {
                    string dxfFileName = Path.ChangeExtension(Path.GetFileName(dwgFile), ".dxf");
                    string dxfPath = Path.Combine(targetDirectory, dxfFileName);

                    if (ConvertDwgToDxf(dwgFile, dxfPath, dxfVersion))
                    {
                        successCount++;
                    }
                }
                catch (Exception ex)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                        $"文件 {dwgFile} 转换失败: {ex.Message}\n");
                }
            }

            return successCount;
        }

        /// <summary>
        /// 使用COM接口进行转换（备用方案）
        /// </summary>
        public static bool ConvertUsingComInterface(string sourceDwgPath, string targetDxfPath)
        {
            object acadApp = null;
            object acadDoc = null;

            try
            {
                // 通过COM接口调用AutoCAD
                Type acadType = Type.GetTypeFromProgID("AutoCAD.Application");
                if (acadType == null)
                {
                    throw new Exception("未找到AutoCAD应用程序");
                }

                acadApp = Activator.CreateInstance(acadType);

                // 打开文档
                object[] openParams = new object[] { sourceDwgPath };
                acadDoc = acadType.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, acadApp, openParams);

                // 保存为DXF
                object[] saveParams = new object[] { targetDxfPath, 82 }; // 82 代表DXF格式
                acadType.InvokeMember("SaveAs", System.Reflection.BindingFlags.InvokeMethod, null, acadDoc, saveParams);

                // 关闭文档
                acadType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, acadDoc, new object[] { false });

                return true;
            }
            catch (Exception ex)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"COM接口转换错误: {ex.Message}\n");
                return false;
            }
            finally
            {
                // 清理COM对象
                if (acadDoc != null)
                {
                    try
                    {
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(acadDoc);
                    }
                    catch { }
                }

                if (acadApp != null)
                {
                    try
                    {
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(acadApp);
                    }
                    catch { }
                }
            }
        }
    }














    public class DwgDxfConverter
    {
        /// <summary>
        /// 将DWG文件转换为DXF格式
        /// </summary>
        public static bool ConvertDwgToDxf(string sourceDwgPath, string targetDxfPath, string dxfVersion = "AC1027")
        {
            // 您的原始实现代码保持不变
            if (string.IsNullOrEmpty(sourceDwgPath))
                throw new ArgumentNullException(nameof(sourceDwgPath));

            if (string.IsNullOrEmpty(targetDxfPath))
                throw new ArgumentNullException(nameof(targetDxfPath));

            if (!File.Exists(sourceDwgPath))
                throw new FileNotFoundException("源DWG文件不存在", sourceDwgPath);

            // 检查目标目录是否存在，不存在则创建
            string targetDirectory = Path.GetDirectoryName(targetDxfPath);
            if (!Directory.Exists(targetDirectory))
            {
                Directory.CreateDirectory(targetDirectory);
            }

            Database database = null;
            bool success = false;

            try
            {
                // 等待文件释放
                if (!WaitForFileRelease(sourceDwgPath, 5000))
                {
                    throw new IOException($"文件被占用，无法访问: {sourceDwgPath}");
                }

                // 创建新的数据库实例
                database = new Database(false, true);

                // 读取DWG文件，使用FileShare.ReadWrite避免共享冲突
                database.ReadDwgFile(sourceDwgPath, FileShare.ReadWrite, true, "");

                // 保存为DXF文件
                database.SaveAs(targetDxfPath, DwgVersion.Current);

                success = true;
                return true;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception acEx)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"AutoCAD错误: {acEx.Message}\n");
                return false;
            }
            catch (System.Exception ex)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"转换错误: {ex.Message}\n");
                return false;
            }
            finally
            {
                // 清理资源
                if (database != null)
                {
                    database.Dispose();
                    database = null;
                }
            }
        }

        /// <summary>
        /// 将DXF文件转换为DWG格式
        /// </summary>
        /// <param name="sourceDxfPath">源DXF文件路径</param>
        /// <param name="targetDwgPath">目标DWG文件路径</param>
        /// <param name="dwgVersion">DWG版本（默认：AC1027 - AutoCAD 2013）</param>
        /// <returns>转换是否成功</returns>
        public static bool ConvertDxfToDwg(string sourceDxfPath, string targetDwgPath, string dwgVersion = "AC1027")
        {
            if (string.IsNullOrEmpty(sourceDxfPath))
                throw new ArgumentNullException(nameof(sourceDxfPath));

            if (string.IsNullOrEmpty(targetDwgPath))
                throw new ArgumentNullException(nameof(targetDwgPath));

            if (!File.Exists(sourceDxfPath))
                throw new FileNotFoundException("源DXF文件不存在", sourceDxfPath);

            // 检查目标目录是否存在，不存在则创建
            string targetDirectory = Path.GetDirectoryName(targetDwgPath);
            if (!Directory.Exists(targetDirectory))
            {
                Directory.CreateDirectory(targetDirectory);
            }

            Database database = null;
            bool success = false;

            try
            {
                // 等待文件释放
                if (!WaitForFileRelease(sourceDxfPath, 5000))
                {
                    throw new IOException($"文件被占用，无法访问: {sourceDxfPath}");
                }

                // 创建新的数据库实例
                database = new Database(false, true);

                // 读取DXF文件
                database.DxfIn(sourceDxfPath, null);

                // 保存为DWG文件
                database.SaveAs(targetDwgPath, DwgVersion.Current);

                success = true;
                return true;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception acEx)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"AutoCAD错误: {acEx.Message}\n");

                // 转换失败时尝试直接修改后缀名
                return TryRenameExtensionAsFallback(sourceDxfPath, targetDwgPath, ".dxf", ".dwg");
            }
            catch (System.Exception ex)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"转换错误: {ex.Message}\n");

                // 转换失败时尝试直接修改后缀名
                return TryRenameExtensionAsFallback(sourceDxfPath, targetDwgPath, ".dxf", ".dwg");
            }
            finally
            {
                // 清理资源
                if (database != null)
                {
                    database.Dispose();
                    database = null;
                }
            }
        }

        /// <summary>
        /// 使用COM接口进行DXF到DWG转换
        /// </summary>
        public static bool ConvertDxfToDwgUsingComInterface(string sourceDxfPath, string targetDwgPath)
        {
            object acadApp = null;
            object acadDoc = null;

            try
            {
                // 通过COM接口调用AutoCAD
                Type acadType = Type.GetTypeFromProgID("AutoCAD.Application");
                if (acadType == null)
                {
                    throw new Exception("未找到AutoCAD应用程序");
                }

                acadApp = Activator.CreateInstance(acadType);

                // 打开DXF文档
                object[] openParams = new object[] { sourceDxfPath };
                acadDoc = acadType.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, acadApp, openParams);

                // 保存为DWG
                object[] saveParams = new object[] { targetDwgPath, 60 }; // 60 代表DWG格式
                acadType.InvokeMember("SaveAs", System.Reflection.BindingFlags.InvokeMethod, null, acadDoc, saveParams);

                // 关闭文档
                acadType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, acadDoc, new object[] { false });

                return true;
            }
            catch (Exception ex)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"COM接口转换错误: {ex.Message}\n");

                // COM转换失败时尝试直接修改后缀名
                return TryRenameExtensionAsFallback(sourceDxfPath, targetDwgPath, ".dxf", ".dwg");
            }
            finally
            {
                // 清理COM对象
                if (acadDoc != null)
                {
                    try
                    {
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(acadDoc);
                    }
                    catch { }
                }

                if (acadApp != null)
                {
                    try
                    {
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(acadApp);
                    }
                    catch { }
                }
            }
        }

        /// <summary>
        /// 转换失败时的备用方案：直接修改文件扩展名
        /// </summary>
        private static bool TryRenameExtensionAsFallback(string sourcePath, string targetPath,
                                                        string sourceExt, string targetExt)
        {
            try
            {
                // 检查源文件扩展名是否符合预期
                if (!sourcePath.EndsWith(sourceExt, StringComparison.OrdinalIgnoreCase))
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                        $"警告：源文件扩展名不是{sourceExt}，无法使用备用方案\n");
                    return false;
                }

                // 检查目标路径扩展名是否符合预期
                if (!targetPath.EndsWith(targetExt, StringComparison.OrdinalIgnoreCase))
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                        $"警告：目标文件扩展名不是{targetExt}，无法使用备用方案\n");
                    return false;
                }

                // 复制文件并修改扩展名
                File.Copy(sourcePath, targetPath, true);

                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"警告：使用备用方案（直接修改扩展名）完成转换\n");

                return true;
            }
            catch (Exception ex)
            {
                Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                    $"备用方案错误: {ex.Message}\n");
                return false;
            }
        }

        /// <summary>
        /// 批量转换DXF文件为DWG格式
        /// </summary>
        public static int BatchConvertDxfToDwg(string sourceDirectory, string targetDirectory,
                                              string searchPattern = "*.dxf", string dwgVersion = "AC1027")
        {
            if (!Directory.Exists(sourceDirectory))
                throw new DirectoryNotFoundException($"源目录不存在: {sourceDirectory}");

            if (!Directory.Exists(targetDirectory))
                Directory.CreateDirectory(targetDirectory);

            string[] dxfFiles = Directory.GetFiles(sourceDirectory, searchPattern);
            int successCount = 0;

            foreach (string dxfFile in dxfFiles)
            {
                try
                {
                    string dwgFileName = Path.ChangeExtension(Path.GetFileName(dxfFile), ".dwg");
                    string dwgPath = Path.Combine(targetDirectory, dwgFileName);

                    if (ConvertDxfToDwg(dxfFile, dwgPath, dwgVersion))
                    {
                        successCount++;
                    }
                }
                catch (Exception ex)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                        $"文件 {dxfFile} 转换失败: {ex.Message}\n");
                }
            }

            return successCount;
        }

        /// <summary>
        /// 等待文件释放（保持不变）
        /// </summary>
        private static bool WaitForFileRelease(string filePath, int timeoutMs, int retryIntervalMs = 100)
        {
            int elapsed = 0;
            while (elapsed < timeoutMs)
            {
                try
                {
                    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        // 文件可访问
                        return true;
                    }
                }
                catch (IOException)
                {
                    // 文件被占用，等待后重试
                    Thread.Sleep(retryIntervalMs);
                    elapsed += retryIntervalMs;
                }
            }
            return false;
        }

        // 保持原有的批量转换DWG到DXF方法
        public static int BatchConvertDwgToDxf(string sourceDirectory, string targetDirectory,
                                              string searchPattern = "*.dwg", string dxfVersion = "AC1027")
        {
            // 实现保持不变
            if (!Directory.Exists(sourceDirectory))
                throw new DirectoryNotFoundException($"源目录不存在: {sourceDirectory}");

            if (!Directory.Exists(targetDirectory))
                Directory.CreateDirectory(targetDirectory);

            string[] dwgFiles = Directory.GetFiles(sourceDirectory, searchPattern);
            int successCount = 0;

            foreach (string dwgFile in dwgFiles)
            {
                try
                {
                    string dxfFileName = Path.ChangeExtension(Path.GetFileName(dwgFile), ".dxf");
                    string dxfPath = Path.Combine(targetDirectory, dxfFileName);

                    if (ConvertDwgToDxf(dwgFile, dxfPath, dxfVersion))
                    {
                        successCount++;
                    }
                }
                catch (Exception ex)
                {
                    Application.DocumentManager.MdiActiveDocument?.Editor.WriteMessage(
                        $"文件 {dwgFile} 转换失败: {ex.Message}\n");
                }
            }

            return successCount;
        }
    }

}
